import { AwakeSystem } from "../../../../../Core/Module/EventSystem/IAwakeSystem";
import { DestroySystem } from "../../../../../Core/Module/EventSystem/IDestroySystem";
import { Log } from "../../../../../Core/Module/Log/Log";
import { ErrorCore } from "../../../../../Core/Module/Network/ErrorCore";
import { TimeHelper } from "../../../../../Core/Module/Time/TimeHelper";
import { ATimer } from "../../../../../Core/Module/Timer/ATimer";
import { TimerComponent } from "../../../../../Core/Module/Timer/TimerComponent";
import { ExpandOf, FriendOf, InvokeAttribute, ObjectSystemAttribute } from "../../../../../Decorator/Decorator";
import { Session } from "../../../../Model/Share/Module/Message/Session";
import { SessionIdleCheckerComponent } from "../../../../Model/Share/Module/Message/SessionIdleCheckerComponent";
import { TimerInvokeType } from "../../../../Model/Share/TimerInvokeType";
import { ConstValue } from "../../ConstValue";


/**
 * 使用 Expand 扩展方法
 * 
 * 必须作出以下申明，才能调用对象的扩展方法
 */
declare module "../../../../Model/Share/Module/Message/SessionIdleCheckerComponent" {

    interface SessionIdleCheckerComponent {

        Check(): void;

    }

}

@ExpandOf(SessionIdleCheckerComponent)
export class SessionIdleCheckerComponentSystem {

    public static readonly CheckInteral: number = 100;

    private static Check(self: SessionIdleCheckerComponent): void {
        let session = self.GetParent<Session>();
        let timeNow = TimeHelper.ClientNow();

        if (timeNow - session.LastRecvTime < ConstValue.SessionTimeoutTime && timeNow - session.LastSendTime < ConstValue.SessionTimeoutTime) {
            return;
        }

        console.info(`session timeout: ${session.Id} ${timeNow} ${session.LastRecvTime} ${session.LastSendTime} ${timeNow - session.LastRecvTime} ${timeNow - session.LastSendTime}`);
        session.Error = ErrorCore.ERR_SessionSendOrRecvTimeout;

        session.Dispose();
    }

}

@InvokeAttribute(TimerInvokeType.SessionIdleChecker)
export class SessionIdleChecker extends ATimer<SessionIdleCheckerComponent> {

    protected override Run(self: SessionIdleCheckerComponent) {
        try {
            self.Check();
        } catch (e) {
            Log.Error(`move timer error: ${self.Id}\n${e}`);
        }
    }
}

@FriendOf(SessionIdleCheckerComponent)
@ObjectSystemAttribute()
export class SessionIdleCheckerComponentAwakeSystem extends AwakeSystem<SessionIdleCheckerComponent> {

    Awake(self: SessionIdleCheckerComponent): void {
        self.RepeatedTimer = TimerComponent.Instance.NewRepeatedTimer(SessionIdleCheckerComponentSystem.CheckInteral, TimerInvokeType.SessionIdleChecker, self);
    }

}

@FriendOf(SessionIdleCheckerComponent)
@ObjectSystemAttribute()
export class SessionIdleCheckerComponentDestroySystem extends DestroySystem<SessionIdleCheckerComponent> {

    Destroy(self: SessionIdleCheckerComponent): void {
        TimerComponent.Instance?.Remove(self.RepeatedTimer);
    }

}